/* This file is the entry of main prigram
 *
 * Copyright (c) 2021 iBenzene, All Rights Reserved
 * 
 * @author: iBenzene, TJU student
 * @e-mail: ibenzene@tju.edu.cn
 */

#include "01_knapsack.h"

static result r = {NAN, NULL};

static void exec(int argc, char *argv[])
{
    int total = atoi(argv[3]);
    int capacity = atoi(argv[4]);
    int *profits = new int[total];
    int *weights = new int[total];
    for (int i = 5, j = 0; j < total; i += 2, j++)
    {
        profits[j] = atoi(argv[i]);
        weights[j] = atoi(argv[i + 1]);
    }
    knapsack bag(total, capacity, profits, weights);
    delete profits;
    delete weights;

    switch (atoi(argv[1]))
    {
    case DP:
        bag.dp();
        break;
    case DFS:
        bag.dfs();
        break;
    case BFS:
        bag.bfs();
        break;
    default:
        printf("no such algorithm: %d\n", atoi(argv[1]));
        break;
    }

    r.optimum = bag.get_optimum();

#ifdef DEBUG
    printf("optimum: %d\nsolution: ", r.optimum);
#endif
    r.solution = new int[total];

    /* copy the solution */
    int *temp = bag.get_solution();
    int i;
    for (i = 0; i < total; i++)
    {
        r.solution[i] = temp[i];
#ifdef DEBUG
        printf("%d ", r.solution[i]);
#endif
    }
    printf("\n");
}

static void check(int argc, char *argv[])
{
    int temp = NAN;
    switch (atoi(argv[2]))
    {
    case 0:
        /* the value mode */
        temp = atoi(argv[argc - 1]);
        if (r.optimum == temp)
            printf("test passed\n");
        else
            printf("test failed: optimum not match\nresult: %d\norigin: %d\n", r.optimum, temp);
        break;
    case 1:
        /* the vector mode */
        temp = 5 + 2 * atoi(argv[3]);
        for (int i = 0, j = temp; j < argc; i++, j++)
        {
            int check = atoi(argv[j]);
            if (check != r.solution[i])
            {
                printf("test failed: solution not match\nindex: %d\nresult: %d\norigin: %d\n", i, r.solution[i], check);
                return;
            }
        }
        printf("test passed\n");
        break;
    case 2:
        /* the mixed mode */
        temp = 5 + 2 * atoi(argv[3]);
        for (int i = 0, j = temp; j < argc - 1; i++, j++)
        {
            int check = atoi(argv[j]);
            if (check != r.solution[i])
            {
                printf("test failed: solution not match\nindex: %d\nresult: %d\norigin: %d\n", i, r.solution[i], check);
                return;
            }
        }
        temp = atoi(argv[argc - 1]);
        if (r.optimum != temp)
        {
            printf("test failed: optimum not match\nresult: %d\norigin: %d\n", r.optimum, temp);
            return;
        }
        printf("test passed\n");
        break;
    default:
        printf("invalid parameter: %d\n", atoi(argv[2]));
        break;
    }
}

int main(int argc, char *argv[])
{
    /* Perform a search operation. */
    exec(argc, argv);

    /* Check search results. */
    check(argc, argv);

    return 0;
}